package io.task.cc.network;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;


/**
 * @author huihui
 */
@Slf4j
@Setter
@Getter
public class ChannelStat implements java.io.Serializable {
    private static final long serialVersionUID = -6942731710053482089L;
    /**
     * 本次解码失败的次数
     */
    public int decodeFailCount = 0;
    /**
     * 最近一次收到业务消息包的时间(一个完整的业务消息包，一部分消息不算)
     */
    public long latestTimeOfReceivedPacket = System.currentTimeMillis();
    /**
     * 最近一次发送业务消息包的时间(一个完整的业务消息包，一部分消息不算)
     */
    public long latestTimeOfSentPacket = System.currentTimeMillis();
    /**
     * 最近一次收到业务消息包的时间:收到字节就算
     */
    public long latestTimeOfReceivedByte = System.currentTimeMillis();
    /**
     * 最近一次发送业务消息包的时间：发送字节就算
     */
    public long latestTimeOfSentByte = System.currentTimeMillis();
    /**
     * ChannelContext对象创建的时间
     */
    public long timeCreated = System.currentTimeMillis();
    /**
     * 第一次连接成功的时间
     */
    public Long timeFirstConnected = null;
    /**
     * 连接关闭的时间
     */
    public long timeClosed = System.currentTimeMillis();
    /**
     * 进入重连队列时间
     */
    public long timeInReconnQueue = System.currentTimeMillis();
    /**
     * 本连接已发送的字节数
     */
    public final AtomicLong sentBytes = new AtomicLong();
    /**
     * 本连接已发送的packet数
     */
    public final AtomicLong sentPackets = new AtomicLong();
    /**
     * 本连接已处理的字节数
     */
    public final AtomicLong handledBytes = new AtomicLong();
    /**
     * 本连接已处理的packet数
     */
    public final AtomicLong handledPackets = new AtomicLong();
    /**
     * 处理消息包耗时，单位：毫秒
     * 拿这个值除以handledPackets，就是处理每个消息包的平均耗时
     */
    public final AtomicLong handledPacketCosts = new AtomicLong();
    /**
     * 本连接已接收的字节数
     */
    public final AtomicLong receivedBytes = new AtomicLong();
    /**
     * 本连接已接收了多少次TCP数据包
     */
    public final AtomicLong receivedTcps = new AtomicLong();
    /**
     * 本连接已接收的packet数
     */
    public final AtomicLong receivedPackets = new AtomicLong();
    /**
     * 心跳超时次数
     */
    public AtomicInteger heartbeatTimeoutCount = new AtomicInteger();

    /**
     * 平均每次TCP接收到的字节数，这个可以用来监控慢攻击，配置PacketsPerTcpReceive定位慢攻击
     */
    public double getBytesPerTcpReceive() {
        if (receivedTcps.get() == 0) {
            return 0;
        }
        double ret = (double) receivedBytes.get() / (double) receivedTcps.get();
        return ret;
    }

    /**
     * 平均每次TCP接收到的业务包数，这个可以用来监控慢攻击，此值越小越有攻击嫌疑
     */
    public double getPacketsPerTcpReceive() {
        if (receivedTcps.get() == 0) {
            return 0;
        }
        double ret = (double) receivedPackets.get() / (double) receivedTcps.get();
        return ret;
    }


    /**
     * 处理packet平均耗时，单位：毫秒
     */
    public double getHandledCostsPerPacket() {
        if (handledPackets.get() > 0) {
            return handledPacketCosts.get() / handledPackets.get();
        }
        return 0;
    }
}
